package com.mlethe.library.recyclerview.adapter;

import static android.view.ViewGroup.LayoutParams;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.content.Context;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.widget.FrameLayout;

import androidx.annotation.IntDef;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.ListUpdateCallback;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

import com.mlethe.library.recyclerview.AdapterLoadSir;
import com.mlethe.library.recyclerview.animation.AlphaInAnimation;
import com.mlethe.library.recyclerview.animation.BaseAnimation;
import com.mlethe.library.recyclerview.animation.ScaleInAnimation;
import com.mlethe.library.recyclerview.animation.SlideInBottomAnimation;
import com.mlethe.library.recyclerview.animation.SlideInLeftAnimation;
import com.mlethe.library.recyclerview.animation.SlideInRightAnimation;
import com.mlethe.library.recyclerview.callback.AbstractLoadCallback;
import com.mlethe.library.recyclerview.callback.Callback;
import com.mlethe.library.recyclerview.diff.AdapterListUpdateCallback;
import com.mlethe.library.recyclerview.diff.BaseDiffCallback;
import com.mlethe.library.recyclerview.entity.IExpandable;
import com.mlethe.library.recyclerview.listener.OnConvertListener;
import com.mlethe.library.recyclerview.listener.OnItemClickListener;
import com.mlethe.library.recyclerview.listener.OnItemLongClickListener;
import com.mlethe.library.recyclerview.listener.OnLoadListener;
import com.mlethe.library.recyclerview.viewholder.SimpleViewHolder;
import com.mlethe.library.recyclerview.viewholder.ViewHolder;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 添加头部 、添加底部、设置Callback
 * Created by Mlethe on 2018/12/28.
 */
public abstract class UniversalAdapter<T, VH extends ViewHolder> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private Context mContext;
    private LayoutInflater mInflater;
    /**
     * 数据列表
     */
    private List<T> mData;
    /**
     * 布局
     */
    private final int mLayoutId;
    /**
     * View绑定数据
     */
    private OnConvertListener<T> mOnConvertListener;
    /**
     * item的点击事件
     */
    private OnItemClickListener<T> mItemClickListener;
    /**
     * item的长按事件
     */
    private OnItemLongClickListener<T> mLongClickListener;

    private static final int BASE_ITEM_TYPE_HEADER = Integer.MAX_VALUE - 20000;
    private static final int BASE_ITEM_TYPE_FOOTER = Integer.MAX_VALUE - 10000;
    public static final int EMPTY_VIEW = Integer.MAX_VALUE;
    public static final int LOADING_VIEW = Integer.MAX_VALUE - 1;

    private FrameLayout mEmptyLayout;
    private int mEmptyWidth = LayoutParams.MATCH_PARENT, mEmptyHeight = LayoutParams.MATCH_PARENT;
    private boolean mIsUseEmpty = false;
    private boolean isEmpty = false;
    private Callback mCallback;
    private View.OnClickListener mOnClickListener;
    private Object mBindData;

    private SparseArray<View> mHeaderViews;
    private SparseArray<View> mFooterViews;
    private boolean mHeadAndEmptyEnable;
    private boolean mFootAndEmptyEnable;

    /**
     * 默认
     */
    private static final int STATE_DEFAULT = 10000;
    /**
     * 加载中
     */
    private static final int STATE_LOADING = 10001;
    /**
     * 加载完成
     */
    private static final int STATE_END = 10002;
    /**
     * 加载失败
     */
    private static final int STATE_FAIL = 10003;
    /**
     * 加载更多状态，Use with {@link #STATE_DEFAULT}，{@link #STATE_LOADING}，{@link #STATE_END}，{@link #STATE_FAIL}
     */
    private int mLoadState = STATE_DEFAULT;
    /**
     * 是否开启底部加载更多
     */
    private boolean mEnableLoadMore = false;
    /**
     * 数据是否全部加载完成，如果完成就不能在触发加载事件
     */
    private boolean mFooterNoMoreData = false;
    /**
     * 底部是否显示数据全部加载完成
     */
    private boolean mFooterNoMoreDataShow = true;
    /**
     * 底部加载更多回调
     */
    private AbstractLoadCallback mLoadCallback;
    /**
     * 底部加载更多点击事件监听
     */
    private OnLoadListener mOnLoadListener;
    /**
     * 控制多出多少条的时候调用 onLoadMore
     */
    private int limitNumberToCallLoadMore = 1;

    private int mSpanCount = -1;

    private boolean mFirstOnlyEnable = true;
    private boolean mOpenAnimationEnable = false;
    private Interpolator mInterpolator = new LinearInterpolator();
    private int mDuration = 300;
    private int mLastPosition = -1;

    private BaseAnimation mCustomAnimation;
    private BaseAnimation mSelectAnimation = new AlphaInAnimation();

    //Animation
    /**
     * Use with {@link #openLoadAnimation}
     */
    public static final int ALPHAIN = 0x00000001;
    /**
     * Use with {@link #openLoadAnimation}
     */
    public static final int SCALEIN = 0x00000002;
    /**
     * Use with {@link #openLoadAnimation}
     */
    public static final int SLIDEIN_BOTTOM = 0x00000003;
    /**
     * Use with {@link #openLoadAnimation}
     */
    public static final int SLIDEIN_LEFT = 0x00000004;
    /**
     * Use with {@link #openLoadAnimation}
     */
    public static final int SLIDEIN_RIGHT = 0x00000005;

    /**
     * 方向 {@link RecyclerView#VERTICAL} {@link RecyclerView#HORIZONTAL}
     */
    private int mOrientation = RecyclerView.VERTICAL;

    @IntDef({ALPHAIN, SCALEIN, SLIDEIN_BOTTOM, SLIDEIN_LEFT, SLIDEIN_RIGHT})
    @Retention(RetentionPolicy.SOURCE)
    public @interface AnimationType {
    }

    public UniversalAdapter() {
        this(new ArrayList<>(), 0);
    }

    public UniversalAdapter(List<T> data) {
        this(data, 0);
    }

    public UniversalAdapter(int layoutId) {
        this(new ArrayList<>(), layoutId);
    }

    public UniversalAdapter(List<T> data, int layoutId) {
        this.mData = data;
        this.mLayoutId = layoutId;
    }

    /**
     * 多布局处理
     *
     * @param item     数据item
     * @param position 位置
     * @return 布局ID
     */
    protected int getLayoutId(T item, int position) {
        return mLayoutId;
    }

    /**
     * 根据当前位置获取不同的viewType
     */
    @Override
    public int getItemViewType(int position) {
        if (isEmptyLayout(position)) {
            return EMPTY_VIEW;
        } else if (isHeaderView(position)) {
            return mHeaderViews.keyAt(position);
        } else if (isFooterView(position)) {
            int size = getEmptyViewCount();
            if (!isEmpty) {
                size = getDataSize();
            }
            return mFooterViews.keyAt(position - getHeaderCount() - size);
        } else if (isLoadView(position)) {
            return LOADING_VIEW;
        }
        int realPos = position - getHeaderCount();
        return getLayoutId(getItem(realPos), realPos);
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == EMPTY_VIEW) {
            if (mEmptyLayout != null) {
                ViewParent viewParent = mEmptyLayout.getParent();
                if (viewParent instanceof ViewGroup) {
                    if (viewParent instanceof RecyclerView) {
                        RecyclerView.LayoutManager layoutManager = ((RecyclerView) viewParent).getLayoutManager();
                        if (layoutManager != null) {
                            layoutManager.removeView(mEmptyLayout);
                        }
                    } else {
                        ((ViewGroup) viewParent).removeView(mEmptyLayout);
                    }
                }
            }
            return createSimpleViewHolder(createEmptyLayout(parent));
        } else if (viewType == LOADING_VIEW) {
            return createSimpleViewHolder(createLoadView(parent));
        } else if (isHeaderViewType(viewType)) {
            View header = mHeaderViews.get(viewType);
            ViewParent viewParent = header.getParent();
            if (viewParent instanceof ViewGroup) {
                if (viewParent instanceof RecyclerView) {
                    RecyclerView.LayoutManager layoutManager = ((RecyclerView) viewParent).getLayoutManager();
                    if (layoutManager != null) {
                        layoutManager.removeView(header);
                    }
                } else {
                    ((ViewGroup) viewParent).removeView(header);
                }
            }
            return createSimpleViewHolder(header);
        } else if (isFooterViewType(viewType)) {
            View footer = mFooterViews.get(viewType);
            ViewParent viewParent = footer.getParent();
            if (viewParent instanceof ViewGroup) {
                if (viewParent instanceof RecyclerView) {
                    RecyclerView.LayoutManager layoutManager = ((RecyclerView) viewParent).getLayoutManager();
                    if (layoutManager != null) {
                        layoutManager.removeView(footer);
                    }
                } else {
                    ((ViewGroup) viewParent).removeView(footer);
                }
            }
            return createSimpleViewHolder(footer);
        }
        View itemView = mInflater.inflate(viewType, parent, false);
        return createViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) {
        int itemViewType = holder.getItemViewType();
        if (itemViewType == EMPTY_VIEW || itemViewType == LOADING_VIEW || isHeaderViewType(itemViewType) || isFooterViewType(itemViewType)) {
            return;
        }
        if (!(holder instanceof ViewHolder)) {
            return;
        }
        int realPos = position - getHeaderCount();
        T item = getItem(realPos);
        if (mOnConvertListener != null) {
            mOnConvertListener.convert((VH) holder, item, realPos);
        }
        convert((VH) holder, item, realPos);
        ViewHolder realHolder = (ViewHolder) holder;
        if (mItemClickListener != null || realHolder.hasClickListener()) {
            holder.itemView.setOnClickListener(v -> {
                int pos = holder.getBindingAdapterPosition();
                if (pos == RecyclerView.NO_POSITION) {
                    return;
                }
                int currPos = pos - getHeaderCount();
                T itemObj = getItem(currPos);
                if (mItemClickListener != null) {
                    mItemClickListener.onItemClick(v, itemObj, realPos);
                }
                ((ViewHolder) holder).onItemClick(v, itemObj, realPos);
            });
        }
        if (mLongClickListener != null || realHolder.hasLongClickListener()) {
            holder.itemView.setOnLongClickListener(v -> {
                int pos = holder.getBindingAdapterPosition();
                if (pos == RecyclerView.NO_POSITION) {
                    return false;
                }
                int currPos = pos - getHeaderCount();
                T itemObj = getItem(currPos);
                if (mLongClickListener != null) {
                    if (mLongClickListener.onLongClick(v, itemObj, realPos)) {
                        return true;
                    }
                }
                return ((ViewHolder) holder).onItemLongClick(v, itemObj, realPos);
            });
        }
    }

    @Override
    public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position, @NonNull List<Object> payloads) {
        if (payloads.isEmpty()) {
            onBindViewHolder(holder, position);
            return;
        }
        int itemViewType = holder.getItemViewType();
        if (itemViewType == EMPTY_VIEW || itemViewType == LOADING_VIEW || isHeaderViewType(itemViewType) || isFooterViewType(itemViewType)) {
            return;
        }
        if (!(holder instanceof ViewHolder)) {
            return;
        }
        int realPos = position - getHeaderCount();
        T item = getItem(realPos);
        if (mOnConvertListener != null) {
            mOnConvertListener.convert((VH) holder, item, realPos, payloads);
        }
        convert((VH) holder, item, realPos, payloads);
        ViewHolder realHolder = (ViewHolder) holder;
        if (mItemClickListener != null || realHolder.hasClickListener()) {
            holder.itemView.setOnClickListener(v -> {
                int pos = holder.getBindingAdapterPosition();
                if (pos == RecyclerView.NO_POSITION) {
                    return;
                }
                int currPos = pos - getHeaderCount();
                T itemObj = getItem(currPos);
                if (mItemClickListener != null) {
                    mItemClickListener.onItemClick(v, itemObj, realPos);
                }
                ((ViewHolder) holder).onItemClick(v, itemObj, realPos);
            });
        }
        if (mLongClickListener != null || realHolder.hasLongClickListener()) {
            holder.itemView.setOnLongClickListener(v -> {
                int pos = holder.getBindingAdapterPosition();
                if (pos == RecyclerView.NO_POSITION) {
                    return false;
                }
                int currPos = pos - getHeaderCount();
                T itemObj = getItem(currPos);
                if (mLongClickListener != null) {
                    if (mLongClickListener.onLongClick(v, itemObj, realPos)) {
                        return true;
                    }
                }
                return ((ViewHolder) holder).onItemLongClick(v, itemObj, realPos);
            });
        }
    }

    @Override
    public int getItemCount() {
        int count;
        int dataSize = getDataSize();
        if (dataSize <= 0 && mIsUseEmpty) {
            isEmpty = true;
            count = getEmptyViewCount();
            if (mHeadAndEmptyEnable) {
                count += getHeaderCount();
            }
            if (mFootAndEmptyEnable) {
                count += getFooterCount();
            }
        } else {
            isEmpty = false;
            count = getHeaderCount() + dataSize + getFooterCount();
            if (getLoadViewCount() == 1) {
                if (mFooterNoMoreData && !mFooterNoMoreDataShow) {
                    return count;
                }
                count++;
            }
        }
        return count;
    }

    @Override
    public void onAttachedToRecyclerView(@NonNull final RecyclerView recyclerView) {
        mContext = recyclerView.getContext();
        mInflater = LayoutInflater.from(mContext);
        recyclerView.addOnScrollListener(mOnScrollListener);
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            final GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
            final GridLayoutManager.SpanSizeLookup spanSizeLookup = gridLayoutManager.getSpanSizeLookup();
            int spanCount = gridLayoutManager.getSpanCount();
            mSpanCount = spanCount;
            gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    if (isEmptyLayout(position) || isHeaderView(position) || isFooterView(position) || isLoadView(position)) {
                        return spanCount;
                    } else if (spanSizeLookup != null) {
                        return spanSizeLookup.getSpanSize(position - getHeaderCount());
                    }
                    return 1;
                }
            });
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
            mSpanCount = staggeredGridLayoutManager.getSpanCount();
        } else {
            mSpanCount = 0;
        }
    }

    @Override
    public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
        int itemViewType = holder.getItemViewType();
        if (itemViewType == EMPTY_VIEW || itemViewType == LOADING_VIEW || isHeaderViewType(itemViewType) || isFooterViewType(itemViewType)) {
            otherViewAttachedToWindow(holder);
        } else {
            addAnimation(holder);
        }
    }

    /**
     * 显示时添加动画
     */
    private void addAnimation(RecyclerView.ViewHolder holder) {
        if (mOpenAnimationEnable) {
            if (!mFirstOnlyEnable || holder.getLayoutPosition() > mLastPosition) {
                BaseAnimation animation;
                if (mCustomAnimation != null) {
                    animation = mCustomAnimation;
                } else {
                    animation = mSelectAnimation;
                }
                startAnim(animation.getAnimators(holder.itemView));
                mLastPosition = holder.getLayoutPosition();
            }
        }
    }

    /**
     * 开始加载动画
     *
     * @param animators 动画数组
     */
    protected void startAnim(Animator[] animators) {
        if (animators != null && animators.length > 0) {
            AnimatorSet animatorSet = new AnimatorSet();
            animatorSet.playTogether(animators);
            animatorSet.setInterpolator(mInterpolator);
            animatorSet.setDuration(mDuration).start();
        }
    }

    /**
     * 瀑布流布局设置头部、底部
     */
    private void otherViewAttachedToWindow(RecyclerView.ViewHolder holder) {
        LayoutParams lp = holder.itemView.getLayoutParams();
        if (lp instanceof StaggeredGridLayoutManager.LayoutParams) {
            StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
            p.setFullSpan(true);
        }
    }

    private final RecyclerView.OnScrollListener mOnScrollListener = new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
            RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
            // 最后一个可见的Item的position
            int lastVisibleItemPosition = -1;
            if (layoutManager instanceof GridLayoutManager) {
                lastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();
            } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                int[] into = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
                ((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(into);
                lastVisibleItemPosition = findMax(into);
            } else if (layoutManager instanceof LinearLayoutManager) {
                lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
            }
            if (lastVisibleItemPosition != -1) {
                int adjAdapterItemCount = layoutManager.getItemCount();
                int childCount = layoutManager.getChildCount();
                if (
                        childCount > 0
                                && lastVisibleItemPosition >= adjAdapterItemCount - limitNumberToCallLoadMore
                                && adjAdapterItemCount >= childCount
                                && !mFooterNoMoreData
                                && (mLoadState == STATE_DEFAULT || mLoadState == STATE_END)
                                && !isEmpty
                ) {
                    mLoadState = STATE_LOADING;
                    if (mLoadCallback != null) {
                        mLoadCallback.onLoading();
                    }
                    if (mOnLoadListener != null) {
                        mOnLoadListener.onLoad();
                    }
                }
            }
        }
    };

    @Override
    public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
        release();
        super.onDetachedFromRecyclerView(recyclerView);
    }

    /**
     * 设置上下文
     *
     * @param context 上下文
     * @return UniversalAdapter<T, VH>
     */
    public UniversalAdapter<T, VH> setContext(Context context) {
        this.mContext = context;
        this.mInflater = LayoutInflater.from(mContext);
        return this;
    }

    /**
     * 获取布局服务
     */
    public LayoutInflater getLayoutInflater() {
        return mInflater;
    }

    /**
     * 获取上下文
     *
     * @return 上下文
     */
    public Context getContext() {
        return mContext;
    }

    /**
     * 获取方向
     *
     * @return 方向 {@link RecyclerView#VERTICAL} {@link RecyclerView#HORIZONTAL}
     */
    public int getOrientation() {
        return mOrientation;
    }

    /**
     * 获取 position
     *
     * @param viewHolder RecyclerView.ViewHolder
     * @return UniversalAdapter<T, VH>
     */
    protected int getViewHolderPosition(RecyclerView.ViewHolder viewHolder) {
        int adapterPosition = viewHolder.getBindingAdapterPosition();
        if (adapterPosition < 0) {
            return adapterPosition;
        }
        return adapterPosition - getHeaderCount();
    }

    /**
     * 判断position是不是数据列表的范围
     *
     * @param position 位置
     * @return 是否在数据列表范围内，true 在
     */
    public boolean inRange(int position) {
        return position >= 0 && position < getDataSize();
    }

    /**
     * 实现数据绑定
     *
     * @param holder   ViewHolder
     * @param item     item
     * @param position 位置
     */
    protected abstract void convert(@NonNull VH holder, T item, int position);

    /**
     * 实现数据绑定
     *
     * @param holder   ViewHolder
     * @param item     item
     * @param position 位置
     * @param payloads 更多
     */
    protected void convert(@NonNull VH holder, T item, int position, @NonNull List<Object> payloads) {
    }

    /**
     * 获取简单的 RecyclerView.ViewHolder
     *
     * @return SimpleViewHolder
     */
    private SimpleViewHolder createSimpleViewHolder(View view) {
        return new SimpleViewHolder(view);
    }

    /**
     * if you want to use subclass of BaseViewHolder in the adapter,
     * you must override the method to create new ViewHolder.
     *
     * @param view view
     * @return new ViewHolder
     */
    @SuppressWarnings("unchecked")
    protected VH createViewHolder(@NonNull View view) {
        Class<?> temp = getClass();
        Class<?> z = null;
        while (z == null && null != temp) {
            z = getInstancedGenericKClass(temp);
            temp = temp.getSuperclass();
        }
        VH vh;
        // 泛型擦除会导致z为null
        if (z == null) {
            vh = (VH) new ViewHolder(view);
        } else {
            vh = createGenericKInstance(z, view);
        }
        return vh != null ? vh : (VH) new ViewHolder(view);
    }

    /**
     * try to create Generic VH instance
     *
     * @param z    clazz
     * @param view view
     * @return ViewHolder
     */
    @SuppressWarnings("unchecked")
    private VH createGenericKInstance(Class<?> z, View view) {
        try {
            Constructor<?> constructor;
            // inner and unstatic class
            if (z.isMemberClass() && !Modifier.isStatic(z.getModifiers())) {
                constructor = z.getDeclaredConstructor(getClass(), View.class);
                constructor.setAccessible(true);
                return (VH) constructor.newInstance(this, view);
            } else {
                constructor = z.getDeclaredConstructor(View.class);
                constructor.setAccessible(true);
                return (VH) constructor.newInstance(view);
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * get generic parameter K
     *
     * @param z clazz
     * @return Class<?>
     */
    private Class<?> getInstancedGenericKClass(Class<?> z) {
        Type type = z.getGenericSuperclass();
        if (type instanceof ParameterizedType) {
            Type[] types = ((ParameterizedType) type).getActualTypeArguments();
            for (Type temp : types) {
                if (temp instanceof Class<?>) {
                    Class<?> tempClass = (Class<?>) temp;
                    if (ViewHolder.class.isAssignableFrom(tempClass)) {
                        return tempClass;
                    }
                } else if (temp instanceof ParameterizedType) {
                    Type rawType = ((ParameterizedType) temp).getRawType();
                    if (rawType instanceof Class && ViewHolder.class.isAssignableFrom((Class<?>) rawType)) {
                        return (Class<?>) rawType;
                    }
                }
            }
        }
        return null;
    }

    /**
     * 释放资源
     */
    public void release() {
        mContext = null;
        mInflater = null;
        if (mData != null) {
            mData.clear();
        }
        mOnConvertListener = null;
        mItemClickListener = null;
        mLongClickListener = null;
        if (mHeaderViews != null) {
            mHeaderViews.clear();
            mHeaderViews = null;
        }
        if (mFooterViews != null) {
            mFooterViews.clear();
            mFooterViews = null;
        }
        releaseCallback();
        mCallback = null;
        mEmptyLayout = null;
        mOnClickListener = null;
        releaseLoadCallback();
        mLoadCallback = null;
        mOnLoadListener = null;
    }

    private void releaseCallback() {
        if (mCallback != null) {
            mCallback.onDestroy();
        }
    }

    private void releaseLoadCallback() {
        if (mLoadCallback != null) {
            mLoadCallback.onDestroy();
        }
    }

    private int findMax(int[] lastPositions) {
        int max = lastPositions[0];
        for (int value : lastPositions) {
            if (value > max) {
                max = value;
            }
        }
        return max;
    }

    /**
     * 创建空视图
     *
     * @param parent 父布局
     * @return 空视图View
     */
    private View createEmptyLayout(@NonNull ViewGroup parent) {
        if (mEmptyLayout == null) {
            mEmptyLayout = new FrameLayout(parent.getContext());
            LayoutParams layoutParams = new LayoutParams(mEmptyWidth, mEmptyHeight);
            mEmptyLayout.setLayoutParams(layoutParams);
        }
        releaseCallback();
        if (mCallback == null) {
            Class<? extends Callback> defaultCallback = AdapterLoadSir.getDefault().getBuilder().getDefaultCallback();
            if (defaultCallback == null) {
                return mEmptyLayout;
            }
            try {
                mCallback = defaultCallback.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (mCallback == null) {
                return mEmptyLayout;
            }
        }
        final View view = mInflater.inflate(mCallback.getLayoutId(), mEmptyLayout, false);
        mCallback.onViewCreated(view);
        mCallback.bindClickListener(mOnClickListener);
        mCallback.bindData(mBindData);
        mEmptyLayout.addView(view);
        return mEmptyLayout;
    }

    /**
     * 创建加载布局
     *
     * @return 创建的view
     */
    private View createLoadView(@NonNull ViewGroup parent) {
        releaseLoadCallback();
        if (mLoadCallback == null) {
            Class<? extends AbstractLoadCallback> callback = AdapterLoadSir.getDefault().getBuilder().getDefaultLoadCallback();
            if (callback == null) {
                throw new IllegalArgumentException("The defaultLoadCallback is not init.");
            }
            try {
                mLoadCallback = callback.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (mLoadCallback == null) {
                throw new IllegalArgumentException(String.format("The LoadCallback (%s) is create fail.", callback.getSimpleName()));
            }
        }
        View view = mInflater.inflate(mLoadCallback.getLayoutId(), parent, false);
        mLoadCallback.onViewCreated(view);
        mLoadCallback.bindClickListener(v -> {
            if (mLoadState != STATE_FAIL) {
                return;
            }
            mLoadState = STATE_LOADING;
            if (mLoadCallback != null) {
                mLoadCallback.onLoading();
            }
            if (mOnLoadListener != null) {
                mOnLoadListener.onReload();
            }
        });
        if (mFooterNoMoreData) {
            if (mLoadCallback != null) {
                mLoadCallback.onNoData();
            }
        } else {
            mLoadState = STATE_LOADING;
            if (mLoadCallback != null) {
                mLoadCallback.onLoading();
            }
            if (mOnLoadListener != null) {
                mOnLoadListener.onLoad();
            }
        }
        return view;
    }

    /**
     * 设置动画类型
     *
     * @param animationType One of {@link #ALPHAIN}, {@link #SCALEIN}, {@link #SLIDEIN_BOTTOM},
     *                      {@link #SLIDEIN_LEFT}, {@link #SLIDEIN_RIGHT}.
     */
    public UniversalAdapter<T, VH> openLoadAnimation(@AnimationType int animationType) {
        this.mOpenAnimationEnable = true;
        mCustomAnimation = null;
        switch (animationType) {
            case ALPHAIN:
                mSelectAnimation = new AlphaInAnimation();
                break;
            case SCALEIN:
                mSelectAnimation = new ScaleInAnimation();
                break;
            case SLIDEIN_BOTTOM:
                mSelectAnimation = new SlideInBottomAnimation();
                break;
            case SLIDEIN_LEFT:
                mSelectAnimation = new SlideInLeftAnimation();
                break;
            case SLIDEIN_RIGHT:
                mSelectAnimation = new SlideInRightAnimation();
                break;
            default:
                break;
        }
        return this;
    }

    /**
     * 设置自定义动画
     *
     * @param animation ObjectAnimator
     */
    public UniversalAdapter<T, VH> openLoadAnimation(BaseAnimation animation) {
        this.mOpenAnimationEnable = true;
        this.mCustomAnimation = animation;
        return this;
    }

    /**
     * 开启item显示动画
     */
    public UniversalAdapter<T, VH> openLoadAnimation() {
        this.mOpenAnimationEnable = true;
        return this;
    }

    /**
     * 关闭item显示动画
     */
    public UniversalAdapter<T, VH> closeLoadAnimation() {
        this.mOpenAnimationEnable = false;
        return this;
    }

    /**
     * 设置动画执行时长
     *
     * @param duration 动画执行时长（毫秒）
     */
    public UniversalAdapter<T, VH> setDuration(int duration) {
        mDuration = duration;
        return this;
    }

    /**
     * 设置动画差值器
     *
     * @param interpolator 动画差值器
     */
    public UniversalAdapter<T, VH> setInterpolator(Interpolator interpolator) {
        mInterpolator = interpolator;
        return this;
    }

    /**
     * {@link #addAnimation(RecyclerView.ViewHolder)}
     *
     * @param firstOnly true 第一次加载时显示动画
     */
    public UniversalAdapter<T, VH> isFirstOnly(boolean firstOnly) {
        this.mFirstOnlyEnable = firstOnly;
        return this;
    }

    /**
     * 设置绑定事件
     *
     * @param listener 绑定事件监听
     * @return UniversalAdapter<T, VH>
     */
    public UniversalAdapter<T, VH> setOnConvertListener(OnConvertListener<T> listener) {
        this.mOnConvertListener = listener;
        return this;
    }

    /**
     * 设置点击事件
     *
     * @param listener item 点击事件
     * @return UniversalAdapter<T, VH>
     */
    public UniversalAdapter<T, VH> setOnItemClickListener(OnItemClickListener<T> listener) {
        this.mItemClickListener = listener;
        return this;
    }

    /**
     * 设置长按事件
     *
     * @param listener item 长按事件
     * @return UniversalAdapter<T, VH>
     */
    public UniversalAdapter<T, VH> setOnItemLongClickListener(OnItemLongClickListener<T> listener) {
        this.mLongClickListener = listener;
        return this;
    }

    /**
     * 设置控制显示加载更多的条数
     *
     * @param limitNumberToCallLoadMore 预显示加载更多的条数
     * @return UniversalAdapter<T, VH>
     */
    public UniversalAdapter<T, VH> setLimitNumberToCallLoadMore(int limitNumberToCallLoadMore) {
        this.limitNumberToCallLoadMore = limitNumberToCallLoadMore;
        return this;
    }

    /**
     * 设置加载更多监听
     *
     * @param listener 加载更多监听
     * @return UniversalAdapter<T, VH>
     */
    public UniversalAdapter<T, VH> setOnLoadListener(OnLoadListener listener) {
        this.mOnLoadListener = listener;
        return this;
    }

    /**
     * 数据加载完成时没有数据的View是否显示
     *
     * @param isShow 数据加载完成时没有数据的View是否显示
     */
    public void setNoDataShow(boolean isShow) {
        this.mFooterNoMoreDataShow = isShow;
    }

    /**
     * 设置是否没有数据了
     *
     * @param noData 是否没有数据了，true 没有数据了
     */
    public void setNoData(boolean noData) {
        this.mFooterNoMoreData = noData;
    }

    /**
     * 加载失败
     */
    public void loadFail() {
        mLoadState = STATE_FAIL;
        if (mLoadCallback != null) {
            mLoadCallback.onLoadFail();
        }
    }

    /**
     * 加载完成
     */
    public void loadFinish() {
        mLoadState = STATE_END;
        if (mFooterNoMoreData) {
            if (mLoadCallback != null) {
                mLoadCallback.onNoData();
            }
        } else {
            if (mLoadCallback != null) {
                mLoadCallback.onLoaded();
            }
        }
    }

    /**
     * 加载完成
     *
     * @param list 数据列表
     */
    public void loadFinish(List<T> list) {
        loadFinish(list, false);
    }

    /**
     * 加载完成
     *
     * @param list      数据列表
     * @param isRefresh 是否刷新未添加数据时最后一行的数据，主要是使用ItemDecoration时使用。
     */
    public void loadFinish(List<T> list, boolean isRefresh) {
        mLoadState = STATE_END;
        int headerCount = getHeaderCount();
        int dataSize = getDataSize();
        if (mFooterNoMoreData) {
            if (mLoadCallback != null) {
                mLoadCallback.onNoData();
            }
            if (mData == null || list == null) {
                return;
            }
            int size = list.size();
            if (size <= 0) {
                return;
            }
            mData.addAll(list);
            notifyItemRangeInserted(headerCount + dataSize, size);
            if (!mFooterNoMoreDataShow) {
                notifyItemRemoved(headerCount + getDataSize() + getFooterCount() + size);
            }
        } else {
            if (mLoadCallback != null) {
                mLoadCallback.onLoaded();
            }
            if (mData == null || list == null) {
                return;
            }
            int size = list.size();
            if (size <= 0) {
                return;
            }
            mData.addAll(list);
            notifyItemRangeInserted(headerCount + dataSize, size);
        }
        if (isRefresh) {
            notifyLastRowChanged(dataSize);
        }
    }

    /**
     * 刷新最后一行(主要是使用ItemDecoration时使用)
     *
     * @param dataSize 添加数据前的数量
     */
    public void notifyLastRowChanged(int dataSize) {
        if (dataSize <= 0) {
            return;
        }
        if (mSpanCount > 0) {
            int startPosition = lastRowStartPosition(dataSize);
            if (startPosition >= 0) {
                int count = dataSize - startPosition;
                notifyItemRangeChanged(getHeaderCount() + startPosition, count);
            }
        } else if (mSpanCount == 0) {
            notifyItemChanged(getHeaderCount() + dataSize - 1);
        }
    }

    /**
     * 获取最后一行开始的position
     *
     * @return 最后一行开始的position
     */
    private int lastRowStartPosition(int itemCount) {
        if (mSpanCount <= 0) {
            return -1;
        }
        if (itemCount % mSpanCount == 0) {
            return (itemCount / mSpanCount - 1) * mSpanCount;
        }
        return itemCount / mSpanCount * mSpanCount;
    }

    /**
     * 设置加载更多
     *
     * @param callback 加载更多的Callback
     * @return UniversalAdapter<T, VH>
     */
    public UniversalAdapter<T, VH> setLoadCallback(Class<? extends AbstractLoadCallback> callback) {
        releaseLoadCallback();
        try {
            mLoadCallback = callback.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (mLoadCallback == null) {
            throw new IllegalArgumentException(String.format("The LoadCallback (%s) is create fail.", callback.getSimpleName()));
        }
        return this;
    }

    /**
     * 设置是否启用上拉加载更多（默认不启用）
     *
     * @param enabled 是否启用
     * @return UniversalAdapter<T, VH>
     */
    public UniversalAdapter<T, VH> setEnableLoadMore(boolean enabled) {
        this.mEnableLoadMore = enabled;
        return this;
    }

    /**
     * 设置默认页面的数据
     *
     * @param data 默认页面绑定的数据
     * @return UniversalAdapter<T, VH>
     */
    public UniversalAdapter<T, VH> setDefaultBindData(Object data) {
        this.mBindData = data;
        return this;
    }


    /**
     * 设置默认页面的点击事件
     *
     * @param listener 默认页面的点击事件
     * @return UniversalAdapter<T, VH>
     */
    public UniversalAdapter<T, VH> setDefaultOnClickListener(View.OnClickListener listener) {
        this.mOnClickListener = listener;
        return this;
    }

    /**
     * 显示默认Callback
     */
    public void showDefaultCallback() {
        showDefaultCallback(false);
    }

    /**
     * 显示默认Callback
     *
     * @param isReplace 相同callback 显示 是否替换显示, true 替换, false 不替换
     */
    public void showDefaultCallback(boolean isReplace) {
        showDefaultCallback(null, isReplace, null);
    }

    /**
     * 显示默认Callback
     *
     * @param data 绑定的数据
     */
    public void showDefaultCallback(Object data) {
        showDefaultCallback(data, false, null);
    }

    /**
     * 显示默认Callback
     *
     * @param listener 点击事件监听
     */
    public void showDefaultCallback(View.OnClickListener listener) {
        showDefaultCallback(null, false, listener);
    }

    /**
     * 显示默认Callback
     *
     * @param data     绑定的数据
     * @param listener 点击事件监听
     */
    public void showDefaultCallback(Object data, View.OnClickListener listener) {
        showDefaultCallback(data, false, listener);
    }

    /**
     * 显示默认Callback
     *
     * @param isReplace 相同callback 显示 是否替换显示, true 替换, false 不替换
     * @param listener  点击事件监听
     */
    public void showDefaultCallback(boolean isReplace, View.OnClickListener listener) {
        showDefaultCallback(null, isReplace, listener);
    }

    /**
     * 显示默认Callback
     *
     * @param data      绑定的数据
     * @param isReplace 相同callback 显示 是否替换显示, true 替换, false 不替换
     * @param listener  点击事件监听
     */
    public void showDefaultCallback(Object data, boolean isReplace, View.OnClickListener listener) {
        Class<? extends Callback> defaultCallback = AdapterLoadSir.getDefault().getBuilder().getDefaultCallback();
        if (defaultCallback == null) {
            throw new IllegalArgumentException("The defaultCallback is not init.");
        }
        showCallback(defaultCallback, data, isReplace, listener);
    }

    /**
     * 显示Callback
     *
     * @param callback 空视图Callback
     */
    public void showCallback(Class<? extends Callback> callback) {
        showCallback(callback, null, false, null);
    }

    /**
     * 显示Callback
     *
     * @param callback 空视图Callback
     * @param data     绑定的数据
     */
    public void showCallback(Class<? extends Callback> callback, Object data) {
        showCallback(callback, data, false, null);
    }

    /**
     * 显示Callback
     *
     * @param callback  空视图Callback
     * @param data      绑定的数据
     * @param isReplace 相同callback 显示 是否替换显示, true 替换, false 不替换
     */
    public void showCallback(Class<? extends Callback> callback, Object data, boolean isReplace) {
        showCallback(callback, data, isReplace, null);
    }

    /**
     * 显示Callback
     *
     * @param callback  空视图Callback
     * @param isReplace 相同callback 显示 是否替换显示, true 替换, false 不替换
     */
    public void showCallback(Class<? extends Callback> callback, boolean isReplace) {
        showCallback(callback, null, isReplace, null);
    }

    /**
     * 显示Callback
     *
     * @param callback 空视图Callback
     * @param listener 点击事件监听
     */
    public void showCallback(Class<? extends Callback> callback, View.OnClickListener listener) {
        showCallback(callback, null, false, listener);
    }

    /**
     * 显示Callback
     *
     * @param callback 空视图Callback
     * @param data     绑定的数据
     * @param listener 点击事件监听
     */
    public void showCallback(Class<? extends Callback> callback, Object data, View.OnClickListener listener) {
        showCallback(callback, data, false, listener);
    }

    /**
     * 显示Callback
     *
     * @param callback  空视图Callback
     * @param data      绑定的数据
     * @param isReplace 相同callback 显示 是否替换显示, true 替换, false 不替换
     * @param listener  点击事件监听
     */
    public final void showCallback(Class<? extends Callback> callback, Object data, boolean isReplace, final View.OnClickListener listener) {
        mBindData = data;
        mOnClickListener = listener;
        if (mCallback != null) {
            if (mCallback.getClass().equals(callback) && !isReplace) {
                mCallback.bindClickListener(mOnClickListener);
                mCallback.bindData(mBindData);
                return;
            }
        }
        releaseCallback();
        try {
            mCallback = callback.newInstance();
            if (mEmptyLayout != null) {
                mEmptyLayout.removeAllViews();
                final View view = mInflater.inflate(mCallback.getLayoutId(), mEmptyLayout, false);
                mCallback.onViewCreated(view);
                mCallback.bindClickListener(mOnClickListener);
                mCallback.bindData(mBindData);
                mEmptyLayout.addView(view);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除空视图
     */
    public void removeEmptyCallback() {
        if (mEmptyLayout != null) {
            mEmptyLayout.removeAllViews();
            mCallback = null;
        }
    }

    /**
     * 设置空视图的宽度和高度
     *
     * @param width  宽度（默认{@link LayoutParams#MATCH_PARENT}）
     * @param height 高度（默认{@link LayoutParams#MATCH_PARENT}）
     * @return UniversalAdapter<T, VH>
     */
    public UniversalAdapter<T, VH> setEmptyWidthAndHeight(int width, int height) {
        this.mEmptyWidth = width;
        this.mEmptyHeight = height;
        return this;
    }

    /**
     * 如果适配器数据为空并且要显示HeaderView和FooterView，则设置isHeadAndEmpty true和isFootAndEmpty true
     *
     * @param isHeadAndEmpty 空视图时是否显示HeaderView（默认：false 不显示HeaderView）
     * @param isFootAndEmpty 空视图时是否显示FooterView（默认：false 不显示FooterView）
     * @return UniversalAdapter<T, VH>
     */
    public UniversalAdapter<T, VH> setHeaderFooterEmpty(boolean isHeadAndEmpty, boolean isFootAndEmpty) {
        mHeadAndEmptyEnable = isHeadAndEmpty;
        mFootAndEmptyEnable = isFootAndEmpty;
        return this;
    }

    /**
     * 设置是否使用空视图
     *
     * @param isUseEmpty 是否使用空视图（默认：false 不使用空视图）
     * @return UniversalAdapter<T, VH>
     */
    public UniversalAdapter<T, VH> isUseEmpty(boolean isUseEmpty) {
        mIsUseEmpty = isUseEmpty;
        return this;
    }

    /**
     * 是否可以使用空视图
     *
     * @return 是否使用空视图
     */
    public boolean isUseEmpty() {
        return mIsUseEmpty;
    }

    /**
     * 添加HeaderView（必须在recyclerView.setLayoutManager()后调用）
     *
     * @param view HeaderView
     * @return UniversalAdapter<T, VH>
     */
    public final UniversalAdapter<T, VH> addHeaderView(View view) {
        if (view == null) {
            return this;
        }
        if (mHeaderViews == null) {
            mHeaderViews = new SparseArray<>();
        }
        int itemType = getHeaderCount() + BASE_ITEM_TYPE_HEADER;
        mHeaderViews.put(itemType, view);
        return this;
    }

    /**
     * setAdapter之后添加HeaderView就调用这个方法
     *
     * @param view HeaderView
     * @return UniversalAdapter<T, VH>
     */
    @Deprecated
    public final UniversalAdapter<T, VH> addHeaderViewAfterSetAdapter(View view) {
        return notifyAddHeaderView(view);
    }

    /**
     * setAdapter之后添加HeaderView就调用这个方法
     *
     * @param view HeaderView
     * @return UniversalAdapter<T, VH>
     */
    public final UniversalAdapter<T, VH> notifyAddHeaderView(View view) {
        if (view == null) {
            return this;
        }
        int headerCount = getHeaderCount();
        addHeaderView(view);
        if (isEmpty) {
            if (mHeadAndEmptyEnable) {
                notifyItemInserted(headerCount);
            }
        } else {
            notifyItemInserted(headerCount);
        }
        return this;
    }

    /**
     * 添加footer（必须在recyclerView.setLayoutManager()后调用）
     *
     * @param view FooterView
     * @return UniversalAdapter<T, VH>
     */
    public final UniversalAdapter<T, VH> addFooterView(View view) {
        if (view == null) {
            return this;
        }
        if (mFooterViews == null) {
            mFooterViews = new SparseArray<>();
        }
        int itemType = getFooterCount() + BASE_ITEM_TYPE_FOOTER;
        mFooterViews.put(itemType, view);
        return this;
    }

    /**
     * setAdapter之后添加FooterView就调用这个方法
     *
     * @param view FooterView
     * @return UniversalAdapter<T, VH>
     */
    @Deprecated
    public final UniversalAdapter<T, VH> addFooterViewAfterSetAdapter(View view) {
        return notifyAddFooterView(view);
    }

    /**
     * setAdapter之后添加FooterView就调用这个方法
     *
     * @param view FooterView
     * @return UniversalAdapter<T, VH>
     */
    public final UniversalAdapter<T, VH> notifyAddFooterView(View view) {
        if (view == null) {
            return this;
        }
        addFooterView(view);
        if (isEmpty) {
            if (mFootAndEmptyEnable) {
                notifyItemInserted(getHeaderCount() + 1 + getFooterCount());
            }
        } else {
            notifyItemInserted(getHeaderCount() + getDataSize() + getFooterCount());
        }
        return this;
    }

    /**
     * 移除HeaderView
     *
     * @param position 位置
     */
    public final void removeHeaderView(int position) {
        int count = getHeaderCount();
        if (mHeaderViews != null && position >= 0 && count >= position) {
            mHeaderViews.removeAt(position);
        }
    }

    /**
     * 移除HeaderView
     *
     * @param view HeaderView
     */
    public final void removeHeaderView(View view) {
        if (mHeaderViews == null || view == null) {
            return;
        }
        int index = mHeaderViews.indexOfValue(view);
        if (index < 0) {
            return;
        }
        removeHeaderView(index);
    }

    /**
     * 删除所有HeaderView
     */
    public final void removeAllHeaders() {
        int count = getHeaderCount();
        if (count > 0) {
            mHeaderViews.clear();
        }
    }

    /**
     * 移除HeaderView，并通知recyclerView刷新
     *
     * @param position 位置
     */
    public final void notifyRemoveHeaderView(int position) {
        int count = getHeaderCount();
        if (mHeaderViews != null && position >= 0 && count >= position) {
            mHeaderViews.removeAt(position);
            if (isEmpty) {
                if (mHeadAndEmptyEnable) {
                    notifyItemRemoved(position);
                }
            } else {
                notifyItemRemoved(position);
                int dataSize = getDataSize();
                if (dataSize > 0) {
                    notifyItemRangeChanged(--count, dataSize);
                }
            }
        }
    }

    /**
     * 移除HeaderView，并通知recyclerView刷新
     *
     * @param view HeaderView
     */
    public final void notifyRemoveHeaderView(View view) {
        if (mHeaderViews == null || view == null) {
            return;
        }
        int index = mHeaderViews.indexOfValue(view);
        if (index < 0) {
            return;
        }
        notifyRemoveHeaderView(index);
    }

    /**
     * 删除所有HeaderView，并通知recyclerView刷新
     */
    public final void notifyRemoveAllHeaders() {
        int count = getHeaderCount();
        if (count > 0) {
            mHeaderViews.clear();
            if (isEmpty) {
                if (mHeadAndEmptyEnable) {
                    notifyItemRangeRemoved(0, count);
                }
            } else {
                notifyItemRangeRemoved(0, count);
                int dataSize = getDataSize();
                if (dataSize > 0) {
                    notifyItemRangeChanged(0, dataSize);
                }
            }
        }
    }

    /**
     * 移除FooterView
     *
     * @param position 位置
     */
    public final void removeFooterView(int position) {
        int count = getFooterCount();
        if (mFooterViews != null && position >= 0 && count >= position) {
            mFooterViews.removeAt(position);
        }
    }

    /**
     * 移除FooterView
     *
     * @param view FooterView
     */
    public final void removeFooterView(View view) {
        if (mFooterViews == null || view == null) {
            return;
        }
        int index = mFooterViews.indexOfValue(view);
        if (index < 0) {
            return;
        }
        removeFooterView(index);
    }

    /**
     * 删除所有FooterView
     */
    public final void removeAllFooters() {
        int count = getFooterCount();
        if (count > 0) {
            mFooterViews.clear();
        }
    }

    /**
     * 移除FooterView，并通知recyclerView刷新
     *
     * @param position 位置
     */
    public final void notifyRemoveFooterView(int position) {
        int count = getFooterCount();
        if (mFooterViews != null && position >= 0 && count >= position) {
            mFooterViews.removeAt(position);
            if (isEmpty) {
                if (mFootAndEmptyEnable) {
                    notifyItemRemoved(getHeaderCount() + 1 + position);
                }
            } else {
                notifyItemRemoved(getHeaderCount() + getDataSize() + position);
            }
        }
    }

    /**
     * 移除FooterView，并通知recyclerView刷新
     *
     * @param view FooterView
     */
    public final void notifyRemoveFooterView(View view) {
        if (mFooterViews == null || view == null) {
            return;
        }
        int index = mFooterViews.indexOfValue(view);
        if (index < 0) {
            return;
        }
        notifyRemoveFooterView(index);
    }

    /**
     * 删除所有FooterView，并通知recyclerView刷新
     */
    public final void notifyRemoveAllFooters() {
        int count = getFooterCount();
        if (count > 0) {
            mFooterViews.clear();
            if (isEmpty) {
                if (mFootAndEmptyEnable) {
                    notifyItemRangeRemoved(getHeaderCount() + 1, count);
                }
            } else {
                notifyItemRangeRemoved(getHeaderCount() + getDataSize(), count);
            }
        }
    }

    /**
     * 获取HeaderView数量
     *
     * @return HeaderView数量
     */
    public final int getHeaderCount() {
        if (mHeaderViews == null) {
            return 0;
        }
        return mHeaderViews.size();
    }

    /**
     * 获取FooterView数量
     *
     * @return FooterView数量
     */
    public final int getFooterCount() {
        if (mFooterViews == null) {
            return 0;
        }
        return mFooterViews.size();
    }

    /**
     * 获取上拉加载更多数量
     *
     * @return 上拉加载更多数量
     */
    private int getLoadViewCount() {
        if (!mEnableLoadMore) {
            return 0;
        }
        if (getDataSize() <= 0) {
            return 0;
        }
        if (!AdapterLoadSir.getDefault().isCommit()) {
            return 0;
        }
        if (AdapterLoadSir.getDefault().getBuilder().getDefaultLoadCallback() == null && mLoadCallback == null) {
            return 0;
        }
        return 1;
    }

    /**
     * 空视图数量
     *
     * @return 空视图数量
     */
    public final int getEmptyViewCount() {
        if (!AdapterLoadSir.getDefault().isCommit()) {
            return 0;
        }
        if (AdapterLoadSir.getDefault().getBuilder().getDefaultCallback() == null && mCallback == null) {
            return 0;
        }
        return 1;
    }

    /**
     * 获取真实的数据列表item条数
     *
     * @return 数据列表item条数
     */
    public final int getDataSize() {
        if (mData != null) {
            return mData.size();
        }
        return 0;
    }

    /**
     * 判断是不是HeaderView
     *
     * @param viewType viewType
     * @return 是否是HeaderView，true 是HeaderView
     */
    public final boolean isHeaderViewType(int viewType) {
        int size = getHeaderCount();
        if (size <= 0) {
            return false;
        }
        if (isEmpty) {
            if (mHeadAndEmptyEnable) {
                return viewType >= BASE_ITEM_TYPE_HEADER && viewType < BASE_ITEM_TYPE_HEADER + size;
            }
            return false;
        }
        return viewType >= BASE_ITEM_TYPE_HEADER && viewType < BASE_ITEM_TYPE_HEADER + size;
    }

    /**
     * 判断是不是FooterView
     *
     * @param viewType viewType
     * @return 是否是FooterView，true 是FooterView
     */
    public final boolean isFooterViewType(int viewType) {
        int size = getFooterCount();
        if (size <= 0) {
            return false;
        }
        if (isEmpty) {
            if (mFootAndEmptyEnable) {
                return viewType >= BASE_ITEM_TYPE_FOOTER && viewType < BASE_ITEM_TYPE_FOOTER + size;
            }
            return false;
        }
        return viewType >= BASE_ITEM_TYPE_FOOTER && viewType < BASE_ITEM_TYPE_FOOTER + size;
    }

    /**
     * 判断是不是HeaderView
     *
     * @param position 位置
     * @return 是否是HeaderView，true 是HeaderView
     */
    public final boolean isHeaderView(int position) {
        int size = getHeaderCount();
        if (size <= 0 || position >= size) {
            return false;
        }
        if (isEmpty) {
            return mHeadAndEmptyEnable;
        }
        return true;
    }

    /**
     * 判断是不是FooterView
     *
     * @param position 位置
     * @return 是否是FooterView，true 是FooterView
     */
    public final boolean isFooterView(int position) {
        int size = getFooterCount();
        if (size <= 0 || position < 0) {
            return false;
        }
        if (isEmpty) {
            if (mFootAndEmptyEnable) {
                int headerCount = getHeaderCount();
                int emptyViewCount = getEmptyViewCount();
                return position >= headerCount + emptyViewCount && position < headerCount + emptyViewCount + size;
            }
        } else {
            int headerCount = getHeaderCount();
            int dataSize = getDataSize();
            return position >= headerCount + dataSize && position < headerCount + dataSize + size;
        }
        return false;
    }

    /**
     * 判断是不是空视图
     *
     * @param position 位置
     * @return 是否是空视图，true 是空视图
     */
    public final boolean isEmptyLayout(int position) {
        if (!isEmpty) {
            return false;
        }
        if (!mHeadAndEmptyEnable) {
            return position == 0;
        }
        if (getEmptyViewCount() != 1) {
            return false;
        }
        return position == getHeaderCount();
    }

    /**
     * 判断是不是空视图
     *
     * @return 是否是空视图，true 是空视图
     */
    protected final boolean isEmptyLayout() {
        if (!mIsUseEmpty) {
            return false;
        }
        if (getDataSize() > 0) {
            return false;
        }
        return true;
    }

    /**
     * 判断是不是加载更多
     *
     * @param position 位置
     * @return 是否是加载更多视图，true 是加载更多视图
     */
    public final boolean isLoadView(int position) {
        if (getLoadViewCount() == 1) {
            if (mFooterNoMoreData && !mFooterNoMoreDataShow) {
                return false;
            }
            return position == getHeaderCount() + getDataSize() + getFooterCount();
        }
        return false;
    }

    /**
     * 获取数据
     *
     * @return 数据列表
     */
    public final List<T> getData() {
        return mData;
    }

    /**
     * 是否是第一个Item
     *
     * @param position 位置
     * @return true 是，false 否
     */
    public final boolean isFirstItem(int position) {
        if (position >= 0 && getDataSize() > position) {
            return position == 0;
        }
        return false;
    }

    /**
     * 是否是最后一个Item
     *
     * @param position 位置
     * @return true 是，false 否
     */
    public final boolean isLastItem(int position) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            return position == dataSize - 1;
        }
        return false;
    }

    /**
     * 格式化数据
     *
     * @param dataList
     * @return
     */
    public List<T> transform(List<T> dataList, int row, int column, int orientation) {
        if (dataList == null || dataList.isEmpty()) {
            return null;
        }
        List<T> destList = new ArrayList<T>();

        int pageSize = row * column;
        int size = dataList.size();

        int afterTransformSize;
        if (size < pageSize) {
            afterTransformSize = pageSize;
        } else if (size % pageSize == 0) {
            afterTransformSize = size;
        } else {
            afterTransformSize = (size / pageSize + 1) * pageSize;
        }

        for (int i = 0; i < afterTransformSize; i++) {
            if (orientation == RecyclerView.VERTICAL) {
                if (i < size) {
                    destList.add(dataList.get(i));
                } else {
                    destList.add(null);
                }
            } else {
                int index = transformIndex(i, row, column);
                if (index >= 0 && index < size) {
                    destList.add(dataList.get(index));
                } else {
                    destList.add(null);
                }
            }
        }

        return destList;
    }

    protected int transformIndex(int index, int row, int column) {
        int pageCount = row * column;

        //current page index
        int curPageIndex = index / pageCount;
        int divisor = index % pageCount;

        int transformIndex = divisor / row + column * (divisor % row);

        //this is very important
        transformIndex += curPageIndex * pageCount;

        return transformIndex;
    }

    /**
     * 获取单条数据
     *
     * @param position 位置
     * @return 数据列表item
     */
    public final T getItem(int position) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            return mData.get(position);
        }
        return null;
    }

    /**
     * 设置新数据
     *
     * @param list 数据列表
     * @return true 需要显示空视图，false 不需要
     */
    public boolean setData(List<T> list) {
        if (mData != null) {
            mData.clear();
        }
        if (list == null || list.size() <= 0) {
            return isEmptyLayout();
        }
        if (mData == null) {
            mData = new ArrayList<>();
        }
        mData.addAll(list);
        return isEmptyLayout();
    }

    /**
     * 添加数据
     *
     * @param element 数据列表item
     */
    public final boolean addItem(T element) {
        if (mData != null) {
            return mData.add(element);
        }
        return false;
    }

    /**
     * 添加数据
     *
     * @param position 位置
     * @param element  数据列表item
     */
    public final void addItem(int position, T element) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            mData.add(position, element);
        }
    }

    /**
     * 添加列表数据
     *
     * @param list 数据列表
     */
    public final boolean addAllItem(List<T> list) {
        if (mData != null && list != null && list.size() > 0) {
            return mData.addAll(list);
        }
        return false;
    }

    /**
     * 添加列表数据
     *
     * @param list 数据列表
     */
    public final boolean addAllItem(int position, List<T> list) {
        int dataSize = getDataSize();
        if (mData != null && position >= 0 && dataSize >= position && list != null && list.size() > 0) {
            return mData.addAll(position, list);
        }
        return false;
    }

    /**
     * 修改数据
     *
     * @param position 位置
     * @param element  数据列表item
     * @return 修改的数据列表item
     */
    public final T setItem(int position, T element) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            return mData.set(position, element);
        }
        return null;
    }

    /**
     * 删除数据
     *
     * @param position 位置
     * @return 删除的数据列表item
     */
    public final T removeItem(int position) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            return mData.remove(position);
        }
        return null;
    }

    /**
     * 删除数据
     *
     * @param element 数据列表item
     * @return 删除的数据列表item
     */
    public final T removeItem(T element) {
        if (mData != null) {
            int index = mData.indexOf(element);
            if (index != -1) {
                return mData.remove(index);
            }
        }
        return null;
    }

    /**
     * 获取数据的index
     *
     * @param element 数据列表item
     * @return 在数据列表的位置
     */
    public final int indexOf(T element) {
        if (element != null && mData != null && !mData.isEmpty()) {
            return mData.indexOf(element);
        }
        return -1;
    }

    /**
     * 移动数据
     *
     * @param fromPosition 移动起始位置
     * @param toPosition   移动结束位置
     */
    public final void moveItem(int fromPosition, int toPosition) {
        moveItem(mData, fromPosition, toPosition);
    }

    /**
     * 移动数据
     *
     * @param fromPosition 移动起始位置
     * @param toPosition   移动结束位置
     */
    public final void moveItem(List<?> list, int fromPosition, int toPosition) {
        if (list == null) return;
        int dataSize = list.size();
        if (fromPosition != toPosition && fromPosition >= 0 && dataSize > fromPosition && toPosition >= 0 && dataSize > toPosition) {
            if (fromPosition < toPosition) {
                for (int i = fromPosition; i < toPosition; i++) {
                    Collections.swap(list, i, i + 1);
                }
            } else {
                for (int i = fromPosition; i > toPosition; i--) {
                    Collections.swap(list, i, i - 1);
                }
            }
        }
    }

    /**
     * 清除数据
     */
    public final void clearItems() {
        if (mData != null) {
            mData.clear();
        }
    }

    /**
     * 使用DiffResult设置新数据
     *
     * @param baseQuickDiffCallback implementation {@link BaseDiffCallback}
     * @return true 需要显示空视图，false 不需要
     */
    public boolean setNewDiffData(@NonNull BaseDiffCallback<T> baseQuickDiffCallback) {
        return setNewDiffData(baseQuickDiffCallback, false);
    }

    /**
     * 使用DiffResult设置新数据
     * <p>
     * 这是异步刷新的方法，如果需要使用异步刷新的方法，请参阅 {@link #setNewDiffData(DiffUtil.DiffResult, List)}.
     *
     * @param baseQuickDiffCallback implementation {@link BaseDiffCallback}
     * @param detectMoves           是否有移动的item
     * @return true 需要显示空视图，false 不需要
     */
    public boolean setNewDiffData(@NonNull BaseDiffCallback<T> baseQuickDiffCallback, boolean detectMoves) {
        List<T> newList = baseQuickDiffCallback.getNewList();
        if (isUseEmpty()) {
            boolean isEmpty = getDataSize() <= 0;
            boolean isEmptyList = newList == null || newList.size() <= 0;
            if (isEmpty || isEmptyList) {
                // 如果当前时空View或新数组是空数组，则直接设置新数据或删除旧数据。
                mData = newList;
                notifyDataSetChanged();
                return isEmptyList;
            }
        }
        baseQuickDiffCallback.setOldList(getData());
        DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(baseQuickDiffCallback, detectMoves);
        diffResult.dispatchUpdatesTo(new AdapterListUpdateCallback(this));
        mData = newList;
        return false;
    }

    /**
     * 使用DiffResult设置新数据
     * <p>
     * 如果需要使用Diff异步计算，请使用此方法。
     * 只需告诉计算结果，此适配器不关心计算过程。
     *
     * @param diffResult DiffResult
     * @param newData    新数据
     * @return true 需要显示空视图，false 不需要
     */
    public boolean setNewDiffData(@NonNull DiffUtil.DiffResult diffResult, List<T> newData) {
        if (isUseEmpty()) {
            boolean isEmpty = getDataSize() <= 0;
            boolean isEmptyList = newData == null || newData.size() <= 0;
            if (isEmpty || isEmptyList) {
                // 如果当前时空View或新数组是空数组，则直接设置新数据或删除旧数据。
                mData = newData;
                notifyDataSetChanged();
                return isEmptyList;
            }
        }
        diffResult.dispatchUpdatesTo(new AdapterListUpdateCallback(this));
        mData = newData;
        return false;
    }

    /**
     * 使用DiffResult设置新数据
     *
     * @param baseQuickDiffCallback implementation {@link BaseDiffCallback}
     * @param listUpdateCallback    implementation {@link ListUpdateCallback}
     * @return true 需要显示空视图，false 不需要
     */
    public boolean setNewDiffData(@NonNull BaseDiffCallback<T> baseQuickDiffCallback, @NonNull ListUpdateCallback listUpdateCallback) {
        return setNewDiffData(baseQuickDiffCallback, listUpdateCallback, false);
    }

    /**
     * 使用DiffResult设置新数据
     * <p>
     * 这是异步刷新的方法，如果需要使用异步刷新的方法，请参阅 {@link #setNewDiffData(DiffUtil.DiffResult, List)}.
     *
     * @param baseQuickDiffCallback implementation {@link BaseDiffCallback}
     * @param listUpdateCallback    implementation {@link ListUpdateCallback}
     * @param detectMoves           是否有移动的item
     * @return true 需要显示空视图，false 不需要
     */
    public boolean setNewDiffData(@NonNull BaseDiffCallback<T> baseQuickDiffCallback, @NonNull ListUpdateCallback listUpdateCallback, boolean detectMoves) {
        List<T> newList = baseQuickDiffCallback.getNewList();
        if (isUseEmpty()) {
            boolean isEmpty = getDataSize() <= 0;
            boolean isEmptyList = newList == null || newList.size() <= 0;
            if (isEmpty || isEmptyList) {
                // 如果当前时空View或新数组是空数组，则直接设置新数据或删除旧数据。
                mData = newList;
                notifyDataSetChanged();
                return isEmptyList;
            }
        }
        baseQuickDiffCallback.setOldList(getData());
        DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(baseQuickDiffCallback, detectMoves);
        diffResult.dispatchUpdatesTo(listUpdateCallback);
        mData = newList;
        return false;
    }

    /**
     * 使用DiffResult设置新数据
     * <p>
     * 如果需要使用Diff异步计算，请使用此方法。
     * 只需告诉计算结果，此适配器不关心计算过程。
     *
     * @param diffResult         DiffResult
     * @param listUpdateCallback implementation {@link ListUpdateCallback}
     * @param newData            新数据
     * @return true 需要显示空视图，false 不需要
     */
    public boolean setNewDiffData(@NonNull DiffUtil.DiffResult diffResult, @NonNull ListUpdateCallback listUpdateCallback, List<T> newData) {
        if (isUseEmpty()) {
            boolean isEmpty = getDataSize() <= 0;
            boolean isEmptyList = newData == null || newData.size() <= 0;
            if (isEmpty || isEmptyList) {
                // 如果当前时空View或新数组是空数组，则直接设置新数据或删除旧数据。
                mData = newData;
                notifyDataSetChanged();
                return isEmptyList;
            }
        }
        diffResult.dispatchUpdatesTo(listUpdateCallback);
        mData = newData;
        return false;
    }

    /**
     * 新数据设置并更新
     *
     * @param list 数据列表
     * @return true 需要显示空视图，false 不需要
     */
    public boolean setNewData(List<T> list) {
        return setNewData(list, false);
    }

    /**
     * 新数据设置并更新
     *
     * @param list     数据列表
     * @param isAddTop 是否是顶部添加
     * @return true 需要显示空视图，false 不需要
     */
    public boolean setNewData(List<T> list, boolean isAddTop) {
        int dataSize = getDataSize();
        if (list == null || list.size() <= 0) {
            if (dataSize > 0) {
                mData.clear();
                if (isEmptyLayout()) {
                    notifyDataSetChanged();
                } else {
                    notifyItemRangeRemoved(getHeaderCount(), dataSize);
                }
            }
            return true;
        }
        boolean isEmpty = isEmptyLayout();
        int size = list.size();
        if (mData == null) {
            mData = new ArrayList<>();
        }
        if (dataSize > 0) {
            mData.clear();
        }
        if (!mData.addAll(list)) {
            if (isEmpty) {
                notifyDataSetChanged();
            } else {
                notifyItemRangeRemoved(getHeaderCount(), dataSize);
            }
            return true;
        }
        if (dataSize > 0) {
            int headerCount = getHeaderCount();
            if (dataSize > size) {
                notifyItemRangeChanged(headerCount, size);
                notifyItemRangeRemoved(headerCount + size, dataSize - size);
            } else if (dataSize < size) {
                if (isAddTop) {
                    int diffCount = size - dataSize;
                    notifyItemRangeInserted(headerCount, diffCount);
                    notifyItemRangeChanged(headerCount + diffCount, dataSize);
                } else {
                    notifyItemRangeChanged(headerCount, dataSize);
                    notifyItemRangeInserted(headerCount + dataSize, size - dataSize);
                }
            } else {
                notifyItemRangeChanged(headerCount, size);
            }
        } else {
            if (isEmpty) {
                notifyDataSetChanged();
            } else {
                notifyItemRangeInserted(getHeaderCount(), size);
            }
        }
        return false;
    }

    /**
     * 添加数据并更新
     *
     * @param element 数据列表item
     * @return true 添加成功，false 添加失败
     */
    public final boolean notifyItemInsert(T element) {
        if (mData != null) {
            int dataSize = getDataSize();
            boolean isEmpty = isEmptyLayout();
            if (mData.add(element)) {
                if (isEmpty) {
                    notifyDataSetChanged();
                } else {
                    notifyItemInserted(getHeaderCount() + dataSize);
                }
                return true;
            }
        }
        return false;
    }

    /**
     * 添加数据并更新
     *
     * @param position 位置
     * @param element  数据列表item
     * @return true 添加成功，false 添加失败
     */
    public final boolean notifyItemInsert(int position, T element) {
        int dataSize = getDataSize();
        if (mData != null && position >= 0 && dataSize >= position) {
            boolean isEmpty = isEmptyLayout();
            mData.add(position, element);
            if (isEmpty) {
                notifyDataSetChanged();
            } else {
                int headerCount = getHeaderCount();
                notifyItemInserted(position + headerCount);
                notifyItemRangeChanged(headerCount + position + 1, dataSize - position);
            }
            return true;
        }
        return false;
    }

    /**
     * 添加列表数据并更新
     *
     * @param list 数据列表
     * @return true 添加成功，false 添加失败
     */
    public final boolean notifyItemInsert(List<T> list) {
        if (mData != null && list != null && list.size() > 0) {
            int size = list.size();
            int dataSize = getDataSize();
            boolean isEmpty = isEmptyLayout();
            if (mData.addAll(list)) {
                if (isEmpty) {
                    notifyDataSetChanged();
                } else {
                    notifyItemRangeInserted(getHeaderCount() + dataSize, size);
                }
                return true;
            }
        }
        return false;
    }

    /**
     * 添加列表数据并更新
     *
     * @param position 位置
     * @param list     数据列表
     * @return true 添加成功，false 添加失败
     */
    public final boolean notifyItemInsert(int position, List<T> list) {
        if (mData != null && list != null && list.size() > 0) {
            int size = list.size();
            int dataSize = getDataSize();
            boolean isEmpty = isEmptyLayout();
            if (mData.addAll(position, list)) {
                if (isEmpty) {
                    notifyDataSetChanged();
                } else {
                    int headerCount = getHeaderCount();
                    notifyItemRangeInserted(headerCount + position, size);
                    int changeCount = dataSize - position;
                    if (changeCount > 0) {
                        notifyItemRangeChanged(headerCount + position + size, dataSize - position);
                    }
                }
                return true;
            }
        }
        return false;
    }

    /**
     * 修改数据并更新
     *
     * @param position 位置
     * @param element  数据列表item
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyDataChange(int position, T element) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            mData.set(position, element);
            notifyItemChanged(position + getHeaderCount());
            return true;
        }
        return false;
    }

    /**
     * 修改数据并更新
     *
     * @param position 位置
     * @param element  数据列表item
     * @param payload  Optional parameter, use null to identify a "full" update
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyItemChange(int position, T element, Object payload) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            mData.set(position, element);
            notifyItemChanged(position + getHeaderCount(), payload);
            return true;
        }
        return false;
    }

    /**
     * 删除数据并更新
     *
     * @param position 位置
     * @return true 需要显示空视图，false 不需要
     */
    public final boolean notifyItemRemove(int position) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            mData.remove(position);
            dataSize--;
            if (dataSize > 0) {
                int start = getHeaderCount() + position;
                notifyItemRemoved(start);
                if (isLastItem(position - 1)) {
                    notifyLastRowChanged(dataSize);
                } else {
                    notifyItemRangeChanged(start, dataSize - position);
                }
                return false;
            } else {
                if (isEmptyLayout()) {
                    notifyDataSetChanged();
                } else {
                    notifyItemRemoved(getHeaderCount());
                }
                return true;
            }
        }
        return dataSize <= 0;
    }

    /**
     * 删除数据并更新
     *
     * @param element 数据列表item
     * @return true 需要显示空视图，false 不需要
     */
    public final boolean notifyItemRemove(T element) {
        if (mData != null) {
            int index = mData.indexOf(element);
            if (index != -1) {
                return notifyItemRemove(index);
            }
            return false;
        }
        return getDataSize() <= 0;
    }

    /**
     * 删除某个位置后面特定条数数据并更新
     *
     * @param positionStart 开始删除的 position (包含)
     * @param itemCount     删除的条数
     * @return true 需要显示空视图，false 不需要
     */
    public final boolean notifyItemRangeRemove(int positionStart, int itemCount) {
        int dataSize = getDataSize();
        if (positionStart >= 0 && dataSize > positionStart && itemCount > 0) {
            int headerCount = getHeaderCount();
            int removePosition = headerCount + positionStart;
            int maxItemCount = dataSize - positionStart;
            if (itemCount > maxItemCount) {
                itemCount = maxItemCount;
            }
            if (positionStart == 0 && maxItemCount == itemCount) {
                mData.clear();
                dataSize = 0;
            } else {
                for (int i = 0; i < itemCount; i++) {
                    mData.remove(positionStart);
                    dataSize--;
                }
            }
            if (!isEmptyLayout()) {
                notifyItemRangeRemoved(getHeaderCount() + positionStart, itemCount);
                if (dataSize > 0) {
                    if (isLastItem(positionStart - 1)) {
                        notifyLastRowChanged(dataSize);
                    } else {
                        notifyItemRangeChanged(removePosition, dataSize - positionStart);
                    }
                    return false;
                }
            } else {
                notifyDataSetChanged();
            }
            return true;
        }
        return dataSize <= 0;
    }

    /**
     * 删除某个位置后面所有的数据并更新
     *
     * @param positionStart 开始删除的 position (包含)
     * @return true 需要显示空视图，false 不需要
     */
    public final boolean notifyItemRangeRemove(int positionStart) {
        int dataSize = getDataSize();
        if (positionStart >= 0 && dataSize > positionStart) {
            int itemCount = dataSize - positionStart;
            if (positionStart == 0) {
                mData.clear();
                dataSize = 0;
            } else {
                for (int i = 0; i < itemCount; i++) {
                    mData.remove(positionStart);
                    dataSize--;
                }
            }
            if (!isEmptyLayout()) {
                notifyItemRangeRemoved(getHeaderCount() + positionStart, itemCount);
                if (dataSize > 0) {
                    notifyLastRowChanged(dataSize);
                    return false;
                }
            } else {
                notifyDataSetChanged();
            }
            return true;
        }
        return dataSize <= 0;
    }

    /**
     * 移动数据并更新
     *
     * @param fromPosition item 上一个位置
     * @param toPosition   item 新位置
     * @return true 移动成功，false 移动失败
     */
    public final boolean notifyItemMove(int fromPosition, int toPosition) {
        int dataSize = getDataSize();
        if (fromPosition != toPosition && fromPosition >= 0 && dataSize > fromPosition && toPosition >= 0 && dataSize > toPosition) {
            if (fromPosition < toPosition) {
                for (int i = fromPosition; i < toPosition; i++) {
                    Collections.swap(mData, i, i + 1);
                }
            } else {
                for (int i = fromPosition; i > toPosition; i--) {
                    Collections.swap(mData, i, i - 1);
                }
            }
            int headerCount = getHeaderCount();
            fromPosition += headerCount;
            toPosition += headerCount;
            notifyItemMoved(fromPosition, toPosition);
            // 解决数据错乱问题
            notifyItemRangeChanged(Math.min(fromPosition, toPosition), Math.abs(fromPosition - toPosition) + 1);
            return true;
        }
        return false;
    }

    /**
     * 清除数据并更新
     *
     * @return true 需要显示空视图，false 不需要
     */
    public final boolean notifyItemClear() {
        int dataSize = getDataSize();
        if (dataSize > 0) {
            mData.clear();
            if (isEmptyLayout()) {
                notifyDataSetChanged();
            } else {
                notifyItemRangeRemoved(getHeaderCount(), dataSize);
            }
        }
        return true;
    }

    /**
     * 更新item
     *
     * @param position item 更新的位置
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyItemChange(int position) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            notifyItemChanged(position + getHeaderCount());
            return true;
        }
        return false;
    }

    /**
     * 更新item
     *
     * @param position item 更新的位置
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyItemChange(int position, Object payload) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            notifyItemChanged(position + getHeaderCount(), payload);
            return true;
        }
        return false;
    }

    /**
     * 更新某个位置后面特定条数的item
     *
     * @param positionStart 开始更新的 position (包含)
     * @param itemCount     更新的条数
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyItemRangeChange(int positionStart, int itemCount) {
        int dataSize = getDataSize();
        if (positionStart >= 0 && dataSize > positionStart && itemCount > 0) {
            int maxItemCount = dataSize - positionStart;
            if (itemCount > maxItemCount) {
                itemCount = maxItemCount;
            }
            notifyItemRangeChanged(positionStart + getHeaderCount(), itemCount);
            return true;
        }
        return false;
    }

    /**
     * 更新某个位置后面特定条数的item
     *
     * @param positionStart 开始更新的 position (包含)
     * @param itemCount     更新的条数
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyItemRangeChange(int positionStart, int itemCount, Object payload) {
        int dataSize = getDataSize();
        if (positionStart >= 0 && dataSize > positionStart && itemCount > 0) {
            int maxItemCount = dataSize - positionStart;
            if (itemCount > maxItemCount) {
                itemCount = maxItemCount;
            }
            notifyItemRangeChanged(positionStart + getHeaderCount(), itemCount, payload);
            return true;
        }
        return false;
    }

    /**
     * 更新某个位置后面所有的item
     *
     * @param positionStart 开始更新的 position (包含)
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyItemRangeChange(int positionStart) {
        int dataSize = getDataSize();
        if (positionStart >= 0 && dataSize > positionStart) {
            notifyItemRangeChanged(positionStart + getHeaderCount(), dataSize - positionStart);
            return true;
        }
        return false;
    }

    /**
     * 更新某个位置后面所有的item
     *
     * @param positionStart 开始更新的 position (包含)
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyItemRangeChange(int positionStart, Object payload) {
        int dataSize = getDataSize();
        if (positionStart >= 0 && dataSize > positionStart) {
            notifyItemRangeChanged(positionStart + getHeaderCount(), dataSize - positionStart, payload);
            return true;
        }
        return false;
    }

    /**
     * 移动数据并更新
     *
     * @param fromPosition item 上一个位置
     * @param toPosition   item 新位置
     * @return true 移动成功，false 移动失败
     */
    public final boolean notifyItemRangeMoved(int fromPosition, int toPosition) {
        int dataSize = getDataSize();
        if (fromPosition != toPosition && fromPosition >= 0 && dataSize > fromPosition && toPosition >= 0 && dataSize > toPosition) {
            int headerCount = getHeaderCount();
            fromPosition += headerCount;
            toPosition += headerCount;
            notifyItemMoved(fromPosition, toPosition);
            // 解决数据错乱问题
            notifyItemRangeChanged(Math.min(fromPosition, toPosition), Math.abs(fromPosition - toPosition) + 1);
            return true;
        }
        return false;
    }

    /**
     * 更新所有数据
     *
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyDataSetChange(Object payload) {
        int dataSize = getDataSize();
        if (dataSize > 0) {
            notifyItemRangeChanged(getHeaderCount(), dataSize, payload);
            return true;
        }
        return false;
    }

    /**
     * 更新所有数据
     *
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyDataSetChange() {
        return notifyDataSetChange(null);
    }

    public boolean hasSubItems(IExpandable item) {
        if (item == null) {
            return false;
        }
        List<T> list = item.getSubItems();
        return list != null && list.size() > 0;
    }

    public boolean isExpandable(T item) {
        return item instanceof IExpandable;
    }

    private IExpandable getExpandableItem(int position) {
        T item = getItem(position);
        if (isExpandable(item)) {
            return (IExpandable) item;
        } else {
            return null;
        }
    }

    /**
     * 展开单个可展开项
     *
     * @param position 位置
     * @param animate  是否需要动画
     * @param notify   是否通知更新
     * @return item 展开的数量
     */
    public int expand(@IntRange(from = 0) int position, boolean animate, boolean notify) {
        IExpandable expandable = getExpandableItem(position);
        if (expandable == null) {
            return 0;
        }
        if (!hasSubItems(expandable)) {
            expandable.setExpanded(true);
            notifyItemChanged(position + getHeaderCount());
            return 0;
        }
        int subItemCount = 0;
        int dataSize = 0;
        if (!expandable.isExpanded()) {
            dataSize = getDataSize();
            List<T> list = expandable.getSubItems();
            subItemCount += recursiveExpand(position + 1, list);
            expandable.setExpanded(true);
        }
        if (notify) {
            if (animate) {
                int headerCount = getHeaderCount();
                notifyItemChanged(headerCount + position);
                if (subItemCount > 0) {
                    int positionStart = headerCount + position + 1;
                    notifyItemRangeInserted(positionStart, subItemCount);
                    int changeCount = dataSize - positionStart;
                    if (changeCount > 0) {
                        notifyItemRangeChanged(positionStart + subItemCount, changeCount);
                    }
                }
            } else {
                notifyDataSetChanged();
            }
        }
        return subItemCount;
    }

    /**
     * 展开单个可展开项
     *
     * @param position 位置
     * @param animate  是否需要动画
     * @return item 展开的数量
     */
    public int expand(@IntRange(from = 0) int position, boolean animate) {
        return expand(position, animate, true);
    }

    /**
     * 展开单个可展开项（有动画）
     *
     * @param position 位置，不包含头部数量
     * @return item 展开的数量
     */
    public int expand(@IntRange(from = 0) int position) {
        return expand(position, true, true);
    }

    /**
     * 仅展开一个所有项
     *
     * @param position 位置
     */
    public void expandAllOnlyOne(int position) {
        expandAllOnlyOne(position, true, true);
    }

    /**
     * 仅展开一个所有项
     *
     * @param position 位置
     * @param notify   是否通知更新
     */
    public void expandAllOnlyOne(int position, boolean notify) {
        expandAllOnlyOne(position, notify, notify);
    }

    /**
     * 仅展开一个所有项
     *
     * @param position 位置
     * @param animate  是否需要动画
     * @param notify   是否通知更新
     */
    public void expandAllOnlyOne(int position, boolean animate, boolean notify) {
        IExpandable expandable = getExpandableItem(position);
        if (expandable == null) {
            return;
        }
        List<Integer> changeList = new ArrayList<>();
        int itemLevel = expandable.getLevel();
        List<T> subItems = expandable.getSubItems();
        int currentPosition = position;
        int startPosition = 0;
        int dataSize = getDataSize();
        for (int i = dataSize - 1; i >= 0; i--) {
            if (i == position) {
                expandable.setExpanded(true);
                changeList.add(i);
                startPosition = i;
                continue;
            }
            T itemTemp = getItem(i);
            if (itemTemp instanceof IExpandable) {
                IExpandable iExpandable = (IExpandable) itemTemp;
                int level = iExpandable.getLevel();
                if (level == itemLevel) {
                    iExpandable.setExpanded(false);
                    changeList.add(i);
                    startPosition = i;
                    continue;
                } else if (level < itemLevel) {
                    changeList.add(i);
                    startPosition = i;
                    continue;
                }
            }
            mData.remove(i);
            if (i < position) {
                currentPosition--;
            }
            startPosition--;
            if (notify && animate) {
                notifyItemRemoved(i);
            }
        }
        if (notify && animate) {
            int changeSize = changeList.size();
            for (int i = changeSize - 1; i >= 0; i--) {
                notifyItemChanged(startPosition + changeSize - 1 - i);
                if (changeList.get(i) == position) {
                    int startIndex = currentPosition + 1;
                    int itemExpandCount = recursiveExpandAll(startIndex, subItems);
                    if (itemExpandCount > 0) {
                        notifyItemRangeInserted(startIndex, itemExpandCount);
                        startPosition += itemExpandCount;
                    }
                }
            }
        }
        if (notify && !animate) {
            notifyDataSetChanged();
        }
    }

    /**
     * 仅展开一个
     *
     * @param position 位置
     */
    public void expandOnlyOne(int position) {
        expandOnlyOne(position, true, true);
    }

    /**
     * 仅展开一个
     *
     * @param position 位置
     * @param notify   是否通知更新
     */
    public void expandOnlyOne(int position, boolean notify) {
        expandOnlyOne(position, notify, notify);
    }

    /**
     * 仅展开一个
     *
     * @param position 位置
     * @param animate  是否需要动画
     * @param notify   是否通知更新
     */
    public void expandOnlyOne(int position, boolean animate, boolean notify) {
        IExpandable expandable = getExpandableItem(position);
        if (expandable == null) {
            return;
        }
        List<Integer> changeList = new ArrayList<>();
        int itemLevel = expandable.getLevel();
        boolean isExpanded = expandable.isExpanded();
        int childStartPos = isExpanded ? position + 1 : -1;
        List<T> subItems = expandable.getSubItems();
        int childEndPos = isExpanded ? childStartPos + recursiveExpendCount(subItems) - 1 : -1;
        int currentPosition = position;
        int startPosition = 0;
        int dataSize = getDataSize();
        for (int i = dataSize - 1; i >= 0; i--) {
            if (i >= childStartPos && i <= childEndPos) {
                changeList.add(i);
                startPosition = i;
                continue;
            } else if (i == position) {
                expandable.setExpanded(true);
                changeList.add(i);
                startPosition = i;
                continue;
            }
            T itemTemp = mData.get(i);
            if (itemTemp instanceof IExpandable) {
                IExpandable iExpandable = (IExpandable) itemTemp;
                int level = iExpandable.getLevel();
                if (level == itemLevel) {
                    iExpandable.setExpanded(false);
                    changeList.add(i);
                    startPosition = i;
                    continue;
                } else if (level < itemLevel) {
                    changeList.add(i);
                    startPosition = i;
                    continue;
                }
            }
            mData.remove(i);
            if (i < position) {
                currentPosition--;
            }
            startPosition--;
            if (notify && animate) {
                notifyItemRemoved(i);
            }
        }
        if (notify && animate) {
            int changeSize = changeList.size();
            for (int i = changeSize - 1; i >= 0; i--) {
                notifyItemChanged(startPosition + changeSize - 1 - i);
                if (changeList.get(i) == position && !isExpanded) {
                    int startIndex = currentPosition + 1;
                    int expandAllCount = recursiveExpand(startIndex, subItems);
                    if (expandAllCount > 0) {
                        notifyItemRangeInserted(startIndex, expandAllCount);
                        startPosition += expandAllCount;
                    }
                }
            }
        }
        if (notify && !animate) {
            notifyDataSetChanged();
        }
    }

    /**
     * 递归展开数据列表
     *
     * @param position 添加的位置
     * @param list     数据列表
     * @return item 展开的数量
     */
    private int recursiveExpand(int position, List<T> list) {
        if (list == null) return 0;
        int count = list.size();
        if (count <= 0) return 0;
        int addCount = 0;
        int currentPosition = position;
        for (int i = 0; i < count; i++) {
            T item = (T) list.get(i);
            mData.add(currentPosition, item);
            addCount++;
            currentPosition++;
            if (item instanceof IExpandable) {
                IExpandable expandable = (IExpandable) item;
                if (expandable.isExpanded() && hasSubItems(expandable)) {
                    List<T> subList = expandable.getSubItems();
                    int itemExpandCount = recursiveExpand(currentPosition, subList);
                    addCount += itemExpandCount;
                    currentPosition += itemExpandCount;
                }
            }
        }
        return addCount;
    }

    /**
     * 递归获取展开的子项的数量
     *
     * @param items list
     * @return item 展开的数量
     */
    private int recursiveExpendCount(List<T> items) {
        int itemCount = 0;
        if (items != null) {
            itemCount = items.size();
            for (T subItem : items) {
                if (subItem instanceof IExpandable) {
                    IExpandable expandable = (IExpandable) subItem;
                    if (expandable.isExpanded()) {
                        itemCount += recursiveExpendCount(expandable.getSubItems());
                    }
                }
            }
        }
        return itemCount;
    }

    /**
     * 展开所有可展开项
     *
     * @param position 位置
     * @param animate  是否需要动画
     * @param notify   是否通知更新
     * @return item 展开的数量
     */
    public int expandAll(int position, boolean animate, boolean notify) {
        IExpandable expandable = getExpandableItem(position);
        if (expandable == null) {
            return 0;
        }
        int expendCount = recursiveExpendCount(expandable.getSubItems());
        int endPosition = Math.min(position + expendCount, getDataSize() - 1);
        int count = 0;
        for (int i = endPosition; i >= position; i--) {
            T item = (T) mData.get(i);
            if (item instanceof IExpandable) {
                IExpandable itemExpandable = (IExpandable) item;
                if (!itemExpandable.isExpanded()) {
                    int itemExpandCount = recursiveExpandAll(i + 1, itemExpandable.getSubItems());
                    itemExpandable.setExpanded(true);
                    count += itemExpandCount;
                    if (notify && animate && itemExpandCount > 0) {
                        notifyItemRangeInserted(i + 1, itemExpandCount);
                    }
                }
            }
        }
        if (notify) {
            if (animate) {
                if (count > 0) {
                    notifyItemRangeChanged(position, getDataSize() - position);
                }
            } else {
                notifyDataSetChanged();
            }
        }
        return count;
    }

    /**
     * 展开所有可展开项
     *
     * @param position 位置
     * @param notify   是否通知更新
     * @return item 展开的数量
     */
    public int expandAll(int position, boolean notify) {
        return expandAll(position, notify, notify);
    }

    /**
     * 递归展开所有子项
     *
     * @param position 添加的位置
     * @param list     数据列表
     * @return item 展开的数量
     */
    private int recursiveExpandAll(int position, List<T> list) {
        if (list == null) return 0;
        int count = list.size();
        if (count <= 0) return 0;
        int addCount = 0;
        int currentPosition = position;
        for (int i = 0; i < count; i++) {
            T item = (T) list.get(i);
            mData.add(currentPosition, item);
            addCount++;
            currentPosition++;
            if (item instanceof IExpandable) {
                IExpandable expandable = (IExpandable) item;
                int itemExpandCount = recursiveExpandAll(currentPosition, expandable.getSubItems());
                addCount += itemExpandCount;
                currentPosition += itemExpandCount;
                expandable.setExpanded(true);
            }
        }
        return addCount;
    }

    /**
     * 展开所有可展开项
     *
     * @param animate 是否需要动画
     * @param notify  是否通知更新
     * @return item 展开的数量
     */
    public int expandAll(boolean animate, boolean notify) {
        int dataSize = getDataSize();
        int count = 0;
        for (int i = dataSize - 1; i >= 0; i--) {
            T item = (T) mData.get(i);
            if (item instanceof IExpandable) {
                IExpandable expandable = (IExpandable) item;
                if (!expandable.isExpanded()) {
                    int itemExpandCount = recursiveExpandAll(i + 1, expandable.getSubItems());
                    expandable.setExpanded(true);
                    count += itemExpandCount;
                    if (notify && animate && itemExpandCount > 0) {
                        notifyItemRangeInserted(i + 1, itemExpandCount);
                    }
                }
            }
        }
        if (notify) {
            if (animate) {
                if (count > 0) {
                    notifyItemRangeChanged(0, dataSize + count);
                }
            } else {
                notifyDataSetChanged();
            }
        }
        return count;
    }

    /**
     * 展开所有可展开项
     *
     * @param notify 是否通知更新
     * @return item 展开的数量
     */
    public int expandAll(boolean notify) {
        return expandAll(notify, notify);
    }

    /**
     * 展开所有可展开项
     *
     * @return item 展开的数量
     */
    public int expandAll() {
        return expandAll(false, false);
    }

    /**
     * 收起所有可收起项
     *
     * @param animate 是否需要动画
     * @param notify  是否通知更新
     * @return item 收起的数量
     */
    public int collapseAll(boolean animate, boolean notify) {
        return collapseAll(0, animate, notify);
    }

    /**
     * 收起所有可收起项
     *
     * @param notify 是否通知更新
     * @return item 收起的数量
     */
    public int collapseAll(boolean notify) {
        return collapseAll(notify, notify);
    }

    /**
     * 收起所有可收起项
     *
     * @return item 收起的数量
     */
    public int collapseAll() {
        return collapseAll(false);
    }

    /**
     * 收起所有展开项
     *
     * @param position 位置
     * @param animate  是否需要动画
     * @param notify   是否通知更新
     * @return item 收起的数量
     */
    public int collapseAll(@IntRange(from = 0) int position, boolean animate, boolean notify) {
        IExpandable expandable = getExpandableItem(position);
        if (expandable == null) {
            return 0;
        }
        int itemLevel = expandable.getLevel();
        int dataSize = getDataSize();
        int count = 0;
        int changeCount = 0;
        for (int i = dataSize - 1; i >= position; i--) {
            T itemTemp = mData.get(i);
            if (itemTemp instanceof IExpandable) {
                IExpandable iExpandable = (IExpandable) itemTemp;
                int level = iExpandable.getLevel();
                if (level == itemLevel) {
                    iExpandable.setExpanded(false);
                    changeCount++;
                    continue;
                } else if (level < itemLevel) {
                    changeCount++;
                    continue;
                }
            }
            mData.remove(i);
            count++;
            if (notify && animate) {
                notifyItemRemoved(i);
            }
        }
        if (notify && animate) {
            if (changeCount > 0) {
                notifyItemRangeChanged(position, changeCount);
            }
        }
        if (notify && !animate) {
            notifyDataSetChanged();
        }
        return count;
    }

    /**
     * 收起单个可展开项
     *
     * @param position 位置
     * @param animate  是否需要动画
     * @param notify   是否通知更新
     * @return item 收起的数量
     */
    public int collapse(@IntRange(from = 0) int position, boolean animate, boolean notify) {
        IExpandable expandable = getExpandableItem(position);
        if (expandable == null) {
            return 0;
        }
        if (!expandable.isExpanded()) {
            return 0;
        }
        int count = 0;
        int expendCount = recursiveExpendCount(expandable.getSubItems());
        int endPosition = Math.min(position + expendCount, getDataSize() - 1);
        for (int i = endPosition; i >= position + 1; i--) {
            mData.remove(i);
            count++;
        }
        expandable.setExpanded(false);
        if (notify) {
            if (animate) {
                int headerCount = getHeaderCount();
                int positionStart = headerCount + position;
                notifyItemRangeRemoved(positionStart + 1, count);
                int changeCount = getDataSize() - positionStart;
                if (changeCount > 0) {
                    notifyItemRangeChanged(positionStart, changeCount);
                }
            } else {
                notifyDataSetChanged();
            }
        }
        return count;
    }

    /**
     * 收起单个可展开项
     *
     * @param position 位置
     * @param animate  是否需要动画
     * @return item 收起的数量
     */
    public int collapse(@IntRange(from = 0) int position, boolean animate) {
        return collapse(position, animate, true);
    }

    /**
     * 收起单个可展开项（有动画）
     *
     * @param position 位置
     * @return item 收起的数量
     */
    public int collapse(@IntRange(from = 0) int position) {
        return collapse(position, true, true);
    }

    /**
     * 获取item的父类
     *
     * @param item item
     * @return 父 position 在数据列表中的位置
     */
    public int getParentPosition(@NonNull T item) {
        // if the item is IExpandable, return a closest IExpandable item position whose level smaller than this.
        // if it is not, return the closest IExpandable item position whose level is not negative
        int level;
        if (item instanceof IExpandable) {
            level = ((IExpandable) item).getLevel();
        } else {
            level = Integer.MAX_VALUE;
        }
        int dataSize = getDataSize();
        int position = -1;
        for (int i = dataSize - 1; i >= 0; i--) {
            T temp = mData.get(i);
            if (item.equals(temp)) {
                position = i;
                if (level == 0) {
                    return position;
                } else if (level < 0) {
                    return -1;
                }
            }
            if (i < position) {
                if (temp instanceof IExpandable) {
                    IExpandable expandable = (IExpandable) temp;
                    int itemLevel = expandable.getLevel();
                    if (itemLevel >= 0 && itemLevel < level) {
                        return i;
                    }
                }
            }
        }
        return -1;
    }

    /**
     * 该方法用于 IExpandable 树形列表。
     * 如果不存在 Parent，则 return -1。
     *
     * @param position 所处列表的位置
     * @return 父 position 在数据列表中的位置
     */
    public int getParentPosition(int position) {
        if (position == -1 || position >= getDataSize()) {
            return -1;
        }
        T item = mData.get(position);

        // if the item is IExpandable, return a closest IExpandable item position whose level smaller than this.
        // if it is not, return the closest IExpandable item position whose level is not negative
        int level;
        if (item instanceof IExpandable) {
            level = ((IExpandable) item).getLevel();
        } else {
            level = Integer.MAX_VALUE;
        }
        if (level == 0) {
            return position;
        } else if (level < 0) {
            return -1;
        }

        for (int i = position; i >= 0; i--) {
            T temp = mData.get(i);
            if (temp instanceof IExpandable) {
                IExpandable expandable = (IExpandable) temp;
                int itemLevel = expandable.getLevel();
                if (itemLevel >= 0 && itemLevel < level) {
                    return i;
                }
            }
        }
        return -1;
    }

    /**
     * 删除子控件
     *
     * @param position 位置
     */
    public void removeChild(@IntRange(from = 0L) int position) {
        removeChild(position, true);
    }

    /**
     * 删除子控件
     *
     * @param position       位置
     * @param isRemoveParent 父控件只有一个子控件时，删除该子控件父控件是否删除。true 删除，否则false
     */
    public void removeChild(@IntRange(from = 0L) int position, boolean isRemoveParent) {
        if (position < 0 || position >= getDataSize()) return;

        T entity = mData.get(position);
        int expendCount = 0;
        if (entity instanceof IExpandable) {
            IExpandable expandable = (IExpandable) entity;
            if (expandable.isExpanded()) {
                expendCount = recursiveExpendCount(expandable.getSubItems());
            }
        }
        int positionStart = position - recursiveRemoveItem(position - 1, entity, isRemoveParent);
        int endPosition = Math.min(position + expendCount, getDataSize() - 1);
        int count = 0;
        for (int i = endPosition; i >= positionStart; i--) {
            mData.remove(i);
            count++;
        }
        notifyItemRangeRemoved(positionStart, count);
        int changeCount = getDataSize() - positionStart;
        if (changeCount > 0) {
            notifyItemRangeChanged(positionStart, changeCount);
        }
    }

    /**
     * 递归删除子控件和父控件
     *
     * @param position       上一个子控件item的位置
     * @param child          子控件item
     * @param isRemoveParent 父控件只有一个子控件时，删除该子控件父控件是否删除。true 删除，否则false
     * @return 可以删除的父控件的个数
     */
    private int recursiveRemoveItem(int position, T child, boolean isRemoveParent) {
        int childLevel = Integer.MAX_VALUE;
        if (child instanceof IExpandable) {
            IExpandable expandable = (IExpandable) child;
            childLevel = expandable.getLevel();
        }
        if (position >= 0 && childLevel > 0) {
            T entity = mData.get(position);
            if (entity instanceof IExpandable) {
                IExpandable expandable = (IExpandable) entity;
                int expandableLevel = expandable.getLevel();
                if (expandableLevel < childLevel) {
                    int count = 0;
                    List<T> subItems = expandable.getSubItems();
                    int subItemSize = 0;
                    if (subItems != null) {
                        subItemSize = subItems.size();
                    }
                    if (subItemSize == 1) {
                        subItems.clear();
                        if (isRemoveParent) {
                            count++;
                            if (expandableLevel > 0) {
                                count += recursiveRemoveItem(position - 1, entity, true);
                            }
                        }
                    } else if (subItemSize > 1) {
                        subItems.remove(child);
                    }
                    return count;
                }
            }
            for (int i = position - 1; i >= 0; i--) {
                T item = mData.get(i);
                if (item instanceof IExpandable) {
                    IExpandable expandable = (IExpandable) item;
                    int expandableLevel = expandable.getLevel();
                    if (expandableLevel < childLevel) {
                        List<T> subItems = expandable.getSubItems();
                        if (subItems != null) {
                            subItems.remove(child);
                            return 0;
                        }
                    }
                }
            }
        }
        return 0;
    }
}
